{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-02-05T06:41:54.955533Z",
     "start_time": "2025-02-05T06:41:52.887159Z"
    }
   },
   "source": [
    "# 导入库\n",
    "import matplotlib as mpl\n",
    "# Matplotlib 绘制的图形会直接嵌入到 Notebook 的输出单元格中，而不是弹出一个独立的窗口\n",
    "%matplotlib inline\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "\n",
    "# os库提供了一种使用操作系统相关功能的便捷方式，允许与操作系统进行交互\n",
    "import os\n",
    "\n",
    "# sys库主要用于处理Python运行时的环境相关信息以及与解释器的交互\n",
    "import sys\n",
    "import time\n",
    "\n",
    "# tqdm库是一个快速，可扩展的Python进度条，可以在 Python 长循环中添加一个进度提示信息，用户只需要封装任意的迭代器 tqdm(iterator)，即可获得一个进度条显示迭代进度。\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "\n",
    "# torch.nn是PyTorch中用于构建神经网络的模块\n",
    "import torch.nn as nn\n",
    "\n",
    "# torch.nn.functional是PyTorch中包含了神经网络的一些常用函数\n",
    "import torch.nn.functional as F"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T06:41:54.960541Z",
     "start_time": "2025-02-05T06:41:54.956537Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# Python 中的一个属性，用于获取当前 Python 解释器的版本信息。它返回一个命名元组（named tuple）\n",
    "print(sys.version_info)\n",
    "\n",
    "# 遍历模块，打印模块名称和版本信息，快速检查当前环境中安装的某些常用 Python 库的版本信息\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "\n",
    "# 判断是否有 GPU，如果有，则使用 GPU 进行训练，否则使用 CPU 进行训练\n",
    "# torch.cuda.is_available()用于判断是否有GPU\n",
    "# torch.device(\"cuda:0\")创建一个 PyTorch 设备对象，表示使用第一个 GPU（索引为 0）\n",
    "# torch.device(\"cpu\")创建一个 PyTorch 设备对象，表示使用 CPU\n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)"
   ],
   "id": "dfe2e666c516082e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.0\n",
      "torch 2.5.1+cpu\n",
      "cpu\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 数据准备",
   "id": "9161beaad9598958"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T06:41:55.015143Z",
     "start_time": "2025-02-05T06:41:54.961045Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing(data_home='data')\n",
    "print(housing.DESCR)\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ],
   "id": "49fec1c1ced5709e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _california_housing_dataset:\n",
      "\n",
      "California Housing dataset\n",
      "--------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      ":Number of Instances: 20640\n",
      "\n",
      ":Number of Attributes: 8 numeric, predictive attributes and the target\n",
      "\n",
      ":Attribute Information:\n",
      "    - MedInc        median income in block group\n",
      "    - HouseAge      median house age in block group\n",
      "    - AveRooms      average number of rooms per household\n",
      "    - AveBedrms     average number of bedrooms per household\n",
      "    - Population    block group population\n",
      "    - AveOccup      average number of household members\n",
      "    - Latitude      block group latitude\n",
      "    - Longitude     block group longitude\n",
      "\n",
      ":Missing Attribute Values: None\n",
      "\n",
      "This dataset was obtained from the StatLib repository.\n",
      "https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html\n",
      "\n",
      "The target variable is the median house value for California districts,\n",
      "expressed in hundreds of thousands of dollars ($100,000).\n",
      "\n",
      "This dataset was derived from the 1990 U.S. census, using one row per census\n",
      "block group. A block group is the smallest geographical unit for which the U.S.\n",
      "Census Bureau publishes sample data (a block group typically has a population\n",
      "of 600 to 3,000 people).\n",
      "\n",
      "A household is a group of people residing within a home. Since the average\n",
      "number of rooms and bedrooms in this dataset are provided per household, these\n",
      "columns may take surprisingly large values for block groups with few households\n",
      "and many empty houses, such as vacation resorts.\n",
      "\n",
      "It can be downloaded/loaded using the\n",
      ":func:`sklearn.datasets.fetch_california_housing` function.\n",
      "\n",
      ".. rubric:: References\n",
      "\n",
      "- Pace, R. Kelley and Ronald Barry, Sparse Spatial Autoregressions,\n",
      "  Statistics and Probability Letters, 33 (1997) 291-297\n",
      "\n",
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T06:41:55.739932Z",
     "start_time": "2025-02-05T06:41:55.735393Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import pprint  #打印的格式比较 好看\n",
    "\n",
    "pprint.pprint(housing.data[0:2])\n",
    "print('-' * 50)\n",
    "pprint.pprint(housing.target[0:2])"
   ],
   "id": "cbcb703544121ddc",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "array([[ 8.32520000e+00,  4.10000000e+01,  6.98412698e+00,\n",
      "         1.02380952e+00,  3.22000000e+02,  2.55555556e+00,\n",
      "         3.78800000e+01, -1.22230000e+02],\n",
      "       [ 8.30140000e+00,  2.10000000e+01,  6.23813708e+00,\n",
      "         9.71880492e-01,  2.40100000e+03,  2.10984183e+00,\n",
      "         3.78600000e+01, -1.22220000e+02]])\n",
      "--------------------------------------------------\n",
      "array([4.526, 3.585])\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T06:54:18.161519Z",
     "start_time": "2025-02-05T06:54:18.144381Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# train_test_split 是用于将数据集随机拆分为训练集和测试集的工具\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# 将完整数据集 housing.data 和对应的标签 housing.target 拆分为训练集（x_train_all 和 y_train_all）和测试集（x_test 和 y_test）\n",
    "#保留一部分数据作为测试集，用于最终评估模型的性能\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state=7)\n",
    "\n",
    "# 将训练集 x_train_all 和 y_train_all 进一步拆分为训练集（x_train 和 y_train）和验证集（x_valid 和 y_valid）\n",
    "# 验证集用于在训练过程中评估模型性能，调整超参数，防止过拟合\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state=11)\n",
    "\n",
    "dataset_maps = {\n",
    "    \"train\": [x_train, y_train],  #训练集\n",
    "    \"valid\": [x_valid, y_valid],  #验证集\n",
    "    \"test\": [x_test, y_test],  #测试集\n",
    "}  #把3个数据集都放到字典中"
   ],
   "id": "8c777d4ba148bc0a",
   "outputs": [],
   "execution_count": 7
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T06:56:36.604288Z",
     "start_time": "2025-02-05T06:56:36.598782Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()  #标准化\n",
    "\n",
    "# fit 方法：计算数据的统计量（如均值、标准差等）或学习数据的特征（如 PCA 的主成分），但不对数据进行转换。\n",
    "# transform 方法：使用 fit 方法学习到的统计量或特征对数据进行转换。\n",
    "# fit_transform 方法：先调用 fit 方法学习统计量或特征，然后调用 transform 方法对数据进行转换。\n",
    "scaler.fit(x_train)"
   ],
   "id": "fbff9a42a4f01cf0",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ],
      "text/html": [
       "<style>#sk-container-id-3 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-3 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-3 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-3 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-3 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-3 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-3 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-3 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-3 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-3 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-3 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-3 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-3 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-3\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-3\" type=\"checkbox\" checked><label for=\"sk-estimator-id-3\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>StandardScaler</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 构建数据集",
   "id": "819ec38a47bc8f6d"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:11:20.820878Z",
     "start_time": "2025-02-05T07:11:20.807884Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 从PyTorch的utils.data模块导入Dataset类，并定义一个名为HousingDataset的新类，继承自Dataset。\n",
    "# Dataset是PyTorch中用于表示数据集的抽象基类\n",
    "# 通过继承Dataset类，我们可以自定义数据集的行为，使其与PyTorch的数据加载器兼容。\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "\n",
    "class HousingDataset(Dataset):\n",
    "\n",
    "    # 初始化方法，根据指定的模式加载数据，并对数据进行预处理\n",
    "    def __init__(self, mode='train'):\n",
    "        self.x, self.y = dataset_maps[mode]\n",
    "        self.x = torch.from_numpy(scaler.transform(self.x)).float()\n",
    "        self.y = torch.from_numpy(self.y).float().reshape(-1, 1)\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.x)\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        return self.x[idx], self.y[idx]\n",
    "\n",
    "\n",
    "train_ds = HousingDataset(\"train\")\n",
    "valid_ds = HousingDataset(\"valid\")\n",
    "test_ds = HousingDataset(\"test\")"
   ],
   "id": "4c6396c9a6951d10",
   "outputs": [],
   "execution_count": 10
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:11:42.116921Z",
     "start_time": "2025-02-05T07:11:42.112253Z"
    }
   },
   "cell_type": "code",
   "source": "type(train_ds)",
   "id": "677671479c791761",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "__main__.HousingDataset"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# Dataloader",
   "id": "3c4c4352f182c75e"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:12:20.301313Z",
     "start_time": "2025-02-05T07:12:20.297848Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from torch.utils.data import DataLoader\n",
    "\n",
    "#放到DataLoader中的train_ds, valid_ds, test_ds都是dataset类型的数据\n",
    "batch_size = 16  #batch_size是可以调的超参数\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(valid_ds, batch_size=batch_size, shuffle=False)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False)"
   ],
   "id": "ba7402a1138ba145",
   "outputs": [],
   "execution_count": 12
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 定义模型",
   "id": "372a335db75464d5"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:13:23.079137Z",
     "start_time": "2025-02-05T07:13:23.076102Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, input_dim=8):\n",
    "        super().__init__()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 1)\n",
    "        )\n",
    "\n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 8]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 1]\n",
    "        return logits"
   ],
   "id": "ab8d29326fdbaddd",
   "outputs": [],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:14:23.401779Z",
     "start_time": "2025-02-05T07:14:23.398732Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        self.patience = patience  #容忍度\n",
    "        self.min_delta = min_delta  #最小变化量\n",
    "        self.best_metric = -1  #最佳指标\n",
    "        self.counter = 0  #计数器\n",
    "\n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            self.best_metric = metric  #更新最佳指标\n",
    "            self.counter = 0  #计数器清零\n",
    "        else:\n",
    "            self.counter += 1  #计数器加一\n",
    "\n",
    "    @property  #定义一个属性，用于判断是否满足early stop条件\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience"
   ],
   "id": "f83cca39d15cac42",
   "outputs": [],
   "execution_count": 15
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:15:13.297384Z",
     "start_time": "2025-02-05T07:15:13.294385Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "\n",
    "@torch.no_grad()  #不计算梯度\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []  #损失列表\n",
    "    for datas, labels in dataloader:  # 遍历验证集\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)  # 验证集损失\n",
    "        loss_list.append(loss.item())  # 损失列表添加损失值\n",
    "\n",
    "    return np.mean(loss_list)  # 计算平均损失值"
   ],
   "id": "a7967f3fa9f46763",
   "outputs": [],
   "execution_count": 17
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:19:23.228949Z",
     "start_time": "2025-02-05T07:18:46.395311Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 训练\n",
    "def training(\n",
    "        model,  #模型\n",
    "        train_loader,  #训练集\n",
    "        val_loader,  #验证集\n",
    "        epoch,  #训练轮数\n",
    "        loss_fct,  #损失函数\n",
    "        optimizer,  #优化器\n",
    "        early_stop_callback=None,  #早停回调函数\n",
    "        eval_step=500,  #每隔多少步进行一次验证集验证\n",
    "):\n",
    "    # 记录训练过程\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "\n",
    "    global_step = 0  #全局步数\n",
    "    model.train()  #训练模式\n",
    "\n",
    "    # 训练\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            for datas, labels in train_loader:  #11610/16=726\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas)  #得到预测值\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    "\n",
    "                loss = loss.cpu().item()  #转为cpu类型，item()是取值\n",
    "                # 记录训练过程\n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "\n",
    "                # 评估\n",
    "                if global_step % eval_step == 0:  #每隔eval_step步进行一次验证集验证\n",
    "                    model.eval()  #验证模式\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)  #验证集损失\n",
    "\n",
    "                    # 记录验证集过程\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "\n",
    "                    model.train()  #训练模式\n",
    "\n",
    "                    # 早停 Early Stop\n",
    "                    if early_stop_callback is not None:  #如果有早停回调函数\n",
    "                        early_stop_callback(-val_loss)  #根据验证集的损失来实现早停\n",
    "                        if early_stop_callback.early_stop:  #如果早停条件满足\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "\n",
    "                # 全局步数加一\n",
    "                global_step += 1\n",
    "                pbar.update(1)  #更新进度条\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})  #设置进度条显示信息\n",
    "\n",
    "    return record_dict  #返回训练过程记录\n",
    "\n",
    "\n",
    "epoch = 100\n",
    "\n",
    "model = NeuralNetwork()  #实例化模型\n",
    "\n",
    "# 1. 定义损失函数 采用MSE损失,均方误差\n",
    "loss_fct = nn.MSELoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=1e-3)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model,\n",
    "    train_loader,\n",
    "    val_loader,\n",
    "    epoch,\n",
    "    loss_fct,\n",
    "    optimizer,\n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    ")"
   ],
   "id": "bfe0d786c5ba8601",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/72600 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "ed821b22e016449f97f3b61a6ccb2cba"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    }
   ],
   "execution_count": 18
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:20:52.729673Z",
     "start_time": "2025-02-05T07:20:52.710610Z"
    }
   },
   "cell_type": "code",
   "source": "record",
   "id": "6fd82e5b98319c32",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'train': [{'loss': 2.9342198371887207, 'step': 0},\n",
       "  {'loss': 2.52628231048584, 'step': 1},\n",
       "  {'loss': 5.6593828201293945, 'step': 2},\n",
       "  {'loss': 3.484984874725342, 'step': 3},\n",
       "  {'loss': 3.02502179145813, 'step': 4},\n",
       "  {'loss': 4.489809989929199, 'step': 5},\n",
       "  {'loss': 4.352811813354492, 'step': 6},\n",
       "  {'loss': 4.3751606941223145, 'step': 7},\n",
       "  {'loss': 4.38559627532959, 'step': 8},\n",
       "  {'loss': 3.3674888610839844, 'step': 9},\n",
       "  {'loss': 4.232493877410889, 'step': 10},\n",
       "  {'loss': 5.597997665405273, 'step': 11},\n",
       "  {'loss': 2.582137107849121, 'step': 12},\n",
       "  {'loss': 3.3671038150787354, 'step': 13},\n",
       "  {'loss': 2.8143057823181152, 'step': 14},\n",
       "  {'loss': 1.617866039276123, 'step': 15},\n",
       "  {'loss': 1.88772714138031, 'step': 16},\n",
       "  {'loss': 1.8823751211166382, 'step': 17},\n",
       "  {'loss': 1.2544690370559692, 'step': 18},\n",
       "  {'loss': 2.7745201587677, 'step': 19},\n",
       "  {'loss': 2.9203779697418213, 'step': 20},\n",
       "  {'loss': 0.9101107716560364, 'step': 21},\n",
       "  {'loss': 1.5662975311279297, 'step': 22},\n",
       "  {'loss': 24.46650505065918, 'step': 23},\n",
       "  {'loss': 2.146592855453491, 'step': 24},\n",
       "  {'loss': 3.3370909690856934, 'step': 25},\n",
       "  {'loss': 2.7563531398773193, 'step': 26},\n",
       "  {'loss': 1.5881893634796143, 'step': 27},\n",
       "  {'loss': 2.0639445781707764, 'step': 28},\n",
       "  {'loss': 2.5171895027160645, 'step': 29},\n",
       "  {'loss': 0.6693167090415955, 'step': 30},\n",
       "  {'loss': 1.749967098236084, 'step': 31},\n",
       "  {'loss': 1.7768027782440186, 'step': 32},\n",
       "  {'loss': 0.9897946715354919, 'step': 33},\n",
       "  {'loss': 1.5709269046783447, 'step': 34},\n",
       "  {'loss': 2.719646453857422, 'step': 35},\n",
       "  {'loss': 1.5368484258651733, 'step': 36},\n",
       "  {'loss': 2.0861668586730957, 'step': 37},\n",
       "  {'loss': 1.7644938230514526, 'step': 38},\n",
       "  {'loss': 1.6723194122314453, 'step': 39},\n",
       "  {'loss': 1.6733105182647705, 'step': 40},\n",
       "  {'loss': 1.2639864683151245, 'step': 41},\n",
       "  {'loss': 1.9440398216247559, 'step': 42},\n",
       "  {'loss': 0.4922031760215759, 'step': 43},\n",
       "  {'loss': 1.8622649908065796, 'step': 44},\n",
       "  {'loss': 0.9418153762817383, 'step': 45},\n",
       "  {'loss': 0.9118034839630127, 'step': 46},\n",
       "  {'loss': 0.327789306640625, 'step': 47},\n",
       "  {'loss': 0.42665964365005493, 'step': 48},\n",
       "  {'loss': 0.7439728379249573, 'step': 49},\n",
       "  {'loss': 0.3265976011753082, 'step': 50},\n",
       "  {'loss': 1.2277344465255737, 'step': 51},\n",
       "  {'loss': 1.1512278318405151, 'step': 52},\n",
       "  {'loss': 1.1742113828659058, 'step': 53},\n",
       "  {'loss': 0.9105664491653442, 'step': 54},\n",
       "  {'loss': 0.47369736433029175, 'step': 55},\n",
       "  {'loss': 0.40348687767982483, 'step': 56},\n",
       "  {'loss': 0.4975191056728363, 'step': 57},\n",
       "  {'loss': 0.5572515726089478, 'step': 58},\n",
       "  {'loss': 1.5812416076660156, 'step': 59},\n",
       "  {'loss': 0.4293353855609894, 'step': 60},\n",
       "  {'loss': 0.9061115980148315, 'step': 61},\n",
       "  {'loss': 2.227698564529419, 'step': 62},\n",
       "  {'loss': 0.8790627121925354, 'step': 63},\n",
       "  {'loss': 0.3371512293815613, 'step': 64},\n",
       "  {'loss': 0.5375595688819885, 'step': 65},\n",
       "  {'loss': 0.40254223346710205, 'step': 66},\n",
       "  {'loss': 1.4317212104797363, 'step': 67},\n",
       "  {'loss': 0.4401407241821289, 'step': 68},\n",
       "  {'loss': 0.4928886890411377, 'step': 69},\n",
       "  {'loss': 0.4618389904499054, 'step': 70},\n",
       "  {'loss': 0.4963529706001282, 'step': 71},\n",
       "  {'loss': 0.9705256223678589, 'step': 72},\n",
       "  {'loss': 0.5969548225402832, 'step': 73},\n",
       "  {'loss': 0.8780300617218018, 'step': 74},\n",
       "  {'loss': 0.8555612564086914, 'step': 75},\n",
       "  {'loss': 0.8282300233840942, 'step': 76},\n",
       "  {'loss': 0.5213294625282288, 'step': 77},\n",
       "  {'loss': 0.26612919569015503, 'step': 78},\n",
       "  {'loss': 0.5451828241348267, 'step': 79},\n",
       "  {'loss': 0.4149957299232483, 'step': 80},\n",
       "  {'loss': 0.2975125014781952, 'step': 81},\n",
       "  {'loss': 0.36170125007629395, 'step': 82},\n",
       "  {'loss': 0.19743959605693817, 'step': 83},\n",
       "  {'loss': 1.4565329551696777, 'step': 84},\n",
       "  {'loss': 0.25747257471084595, 'step': 85},\n",
       "  {'loss': 0.3597138822078705, 'step': 86},\n",
       "  {'loss': 0.6411042809486389, 'step': 87},\n",
       "  {'loss': 0.5578144192695618, 'step': 88},\n",
       "  {'loss': 0.5232602953910828, 'step': 89},\n",
       "  {'loss': 0.3209776282310486, 'step': 90},\n",
       "  {'loss': 0.9163804054260254, 'step': 91},\n",
       "  {'loss': 0.44646313786506653, 'step': 92},\n",
       "  {'loss': 0.7429690957069397, 'step': 93},\n",
       "  {'loss': 0.5218464732170105, 'step': 94},\n",
       "  {'loss': 0.5117220878601074, 'step': 95},\n",
       "  {'loss': 0.8495652079582214, 'step': 96},\n",
       "  {'loss': 0.8229241371154785, 'step': 97},\n",
       "  {'loss': 2.0101118087768555, 'step': 98},\n",
       "  {'loss': 0.6888533234596252, 'step': 99},\n",
       "  {'loss': 0.33038273453712463, 'step': 100},\n",
       "  {'loss': 0.48953261971473694, 'step': 101},\n",
       "  {'loss': 0.5128592252731323, 'step': 102},\n",
       "  {'loss': 0.43213996291160583, 'step': 103},\n",
       "  {'loss': 1.4088473320007324, 'step': 104},\n",
       "  {'loss': 0.9078068733215332, 'step': 105},\n",
       "  {'loss': 0.5290197730064392, 'step': 106},\n",
       "  {'loss': 0.8553227782249451, 'step': 107},\n",
       "  {'loss': 0.333466112613678, 'step': 108},\n",
       "  {'loss': 0.8352618217468262, 'step': 109},\n",
       "  {'loss': 0.47131094336509705, 'step': 110},\n",
       "  {'loss': 0.20527103543281555, 'step': 111},\n",
       "  {'loss': 0.7280259132385254, 'step': 112},\n",
       "  {'loss': 4.487785339355469, 'step': 113},\n",
       "  {'loss': 0.4878525733947754, 'step': 114},\n",
       "  {'loss': 0.5212041139602661, 'step': 115},\n",
       "  {'loss': 0.2132112979888916, 'step': 116},\n",
       "  {'loss': 0.2650241255760193, 'step': 117},\n",
       "  {'loss': 0.30783167481422424, 'step': 118},\n",
       "  {'loss': 1.1879724264144897, 'step': 119},\n",
       "  {'loss': 0.5346922278404236, 'step': 120},\n",
       "  {'loss': 0.6109559535980225, 'step': 121},\n",
       "  {'loss': 0.07631279528141022, 'step': 122},\n",
       "  {'loss': 0.30404478311538696, 'step': 123},\n",
       "  {'loss': 0.6599363088607788, 'step': 124},\n",
       "  {'loss': 0.8243297934532166, 'step': 125},\n",
       "  {'loss': 0.17225158214569092, 'step': 126},\n",
       "  {'loss': 1.1484308242797852, 'step': 127},\n",
       "  {'loss': 0.6791605353355408, 'step': 128},\n",
       "  {'loss': 1.806980848312378, 'step': 129},\n",
       "  {'loss': 0.7206897735595703, 'step': 130},\n",
       "  {'loss': 0.7564213871955872, 'step': 131},\n",
       "  {'loss': 0.7702094316482544, 'step': 132},\n",
       "  {'loss': 0.6881692409515381, 'step': 133},\n",
       "  {'loss': 1.0429458618164062, 'step': 134},\n",
       "  {'loss': 0.5863040685653687, 'step': 135},\n",
       "  {'loss': 1.3542447090148926, 'step': 136},\n",
       "  {'loss': 0.4064256250858307, 'step': 137},\n",
       "  {'loss': 0.7934128046035767, 'step': 138},\n",
       "  {'loss': 1.0718148946762085, 'step': 139},\n",
       "  {'loss': 0.45874306559562683, 'step': 140},\n",
       "  {'loss': 0.5581713914871216, 'step': 141},\n",
       "  {'loss': 1.5843867063522339, 'step': 142},\n",
       "  {'loss': 0.4952731728553772, 'step': 143},\n",
       "  {'loss': 0.597174882888794, 'step': 144},\n",
       "  {'loss': 0.9934247136116028, 'step': 145},\n",
       "  {'loss': 0.20770186185836792, 'step': 146},\n",
       "  {'loss': 0.29482755064964294, 'step': 147},\n",
       "  {'loss': 0.5109478235244751, 'step': 148},\n",
       "  {'loss': 0.2919692397117615, 'step': 149},\n",
       "  {'loss': 0.301166832447052, 'step': 150},\n",
       "  {'loss': 0.6939103007316589, 'step': 151},\n",
       "  {'loss': 0.3972347378730774, 'step': 152},\n",
       "  {'loss': 0.2532845139503479, 'step': 153},\n",
       "  {'loss': 0.5445605516433716, 'step': 154},\n",
       "  {'loss': 0.33174198865890503, 'step': 155},\n",
       "  {'loss': 1.8417705297470093, 'step': 156},\n",
       "  {'loss': 0.5058149695396423, 'step': 157},\n",
       "  {'loss': 0.6742575168609619, 'step': 158},\n",
       "  {'loss': 0.4862118065357208, 'step': 159},\n",
       "  {'loss': 0.5175928473472595, 'step': 160},\n",
       "  {'loss': 0.8362681865692139, 'step': 161},\n",
       "  {'loss': 0.6013513803482056, 'step': 162},\n",
       "  {'loss': 1.2928402423858643, 'step': 163},\n",
       "  {'loss': 0.5698725581169128, 'step': 164},\n",
       "  {'loss': 0.691648542881012, 'step': 165},\n",
       "  {'loss': 0.2155371755361557, 'step': 166},\n",
       "  {'loss': 2.084449291229248, 'step': 167},\n",
       "  {'loss': 0.7015314102172852, 'step': 168},\n",
       "  {'loss': 0.1726941466331482, 'step': 169},\n",
       "  {'loss': 0.3064938187599182, 'step': 170},\n",
       "  {'loss': 0.45532387495040894, 'step': 171},\n",
       "  {'loss': 0.7121102213859558, 'step': 172},\n",
       "  {'loss': 1.149519681930542, 'step': 173},\n",
       "  {'loss': 0.4379780888557434, 'step': 174},\n",
       "  {'loss': 0.3675585985183716, 'step': 175},\n",
       "  {'loss': 0.8752031922340393, 'step': 176},\n",
       "  {'loss': 1.0908523797988892, 'step': 177},\n",
       "  {'loss': 0.24251516163349152, 'step': 178},\n",
       "  {'loss': 0.903154730796814, 'step': 179},\n",
       "  {'loss': 0.5697799324989319, 'step': 180},\n",
       "  {'loss': 0.305419921875, 'step': 181},\n",
       "  {'loss': 0.29977962374687195, 'step': 182},\n",
       "  {'loss': 0.5513344407081604, 'step': 183},\n",
       "  {'loss': 0.17858393490314484, 'step': 184},\n",
       "  {'loss': 0.2862679362297058, 'step': 185},\n",
       "  {'loss': 0.34423649311065674, 'step': 186},\n",
       "  {'loss': 0.2529192864894867, 'step': 187},\n",
       "  {'loss': 0.532956063747406, 'step': 188},\n",
       "  {'loss': 0.4821373224258423, 'step': 189},\n",
       "  {'loss': 0.31512755155563354, 'step': 190},\n",
       "  {'loss': 0.36670416593551636, 'step': 191},\n",
       "  {'loss': 1.0624150037765503, 'step': 192},\n",
       "  {'loss': 0.18331146240234375, 'step': 193},\n",
       "  {'loss': 0.7325378656387329, 'step': 194},\n",
       "  {'loss': 0.7488418221473694, 'step': 195},\n",
       "  {'loss': 0.7462344169616699, 'step': 196},\n",
       "  {'loss': 0.3313809633255005, 'step': 197},\n",
       "  {'loss': 0.5409354567527771, 'step': 198},\n",
       "  {'loss': 0.5998246669769287, 'step': 199},\n",
       "  {'loss': 0.22895026206970215, 'step': 200},\n",
       "  {'loss': 0.28771689534187317, 'step': 201},\n",
       "  {'loss': 0.16534416377544403, 'step': 202},\n",
       "  {'loss': 0.4894872009754181, 'step': 203},\n",
       "  {'loss': 0.9051209688186646, 'step': 204},\n",
       "  {'loss': 0.4242344796657562, 'step': 205},\n",
       "  {'loss': 0.6040892601013184, 'step': 206},\n",
       "  {'loss': 0.28185373544692993, 'step': 207},\n",
       "  {'loss': 0.4834141135215759, 'step': 208},\n",
       "  {'loss': 1.4279900789260864, 'step': 209},\n",
       "  {'loss': 0.9242060780525208, 'step': 210},\n",
       "  {'loss': 0.09508109092712402, 'step': 211},\n",
       "  {'loss': 0.22654232382774353, 'step': 212},\n",
       "  {'loss': 0.40567493438720703, 'step': 213},\n",
       "  {'loss': 0.4161860942840576, 'step': 214},\n",
       "  {'loss': 0.4667705297470093, 'step': 215},\n",
       "  {'loss': 0.49162209033966064, 'step': 216},\n",
       "  {'loss': 0.3479069471359253, 'step': 217},\n",
       "  {'loss': 0.5372945070266724, 'step': 218},\n",
       "  {'loss': 0.22232642769813538, 'step': 219},\n",
       "  {'loss': 0.20750738680362701, 'step': 220},\n",
       "  {'loss': 0.2909626364707947, 'step': 221},\n",
       "  {'loss': 0.7272419929504395, 'step': 222},\n",
       "  {'loss': 0.5606276392936707, 'step': 223},\n",
       "  {'loss': 0.27286243438720703, 'step': 224},\n",
       "  {'loss': 0.3854568898677826, 'step': 225},\n",
       "  {'loss': 0.37848636507987976, 'step': 226},\n",
       "  {'loss': 0.236137256026268, 'step': 227},\n",
       "  {'loss': 0.5474165678024292, 'step': 228},\n",
       "  {'loss': 0.3840244710445404, 'step': 229},\n",
       "  {'loss': 0.32113903760910034, 'step': 230},\n",
       "  {'loss': 0.3662673234939575, 'step': 231},\n",
       "  {'loss': 0.19417452812194824, 'step': 232},\n",
       "  {'loss': 0.8365245461463928, 'step': 233},\n",
       "  {'loss': 0.556058406829834, 'step': 234},\n",
       "  {'loss': 0.14291733503341675, 'step': 235},\n",
       "  {'loss': 0.32001495361328125, 'step': 236},\n",
       "  {'loss': 0.9655044078826904, 'step': 237},\n",
       "  {'loss': 1.0566856861114502, 'step': 238},\n",
       "  {'loss': 0.5456788539886475, 'step': 239},\n",
       "  {'loss': 0.38773247599601746, 'step': 240},\n",
       "  {'loss': 0.7584977149963379, 'step': 241},\n",
       "  {'loss': 0.8217490315437317, 'step': 242},\n",
       "  {'loss': 0.7045604586601257, 'step': 243},\n",
       "  {'loss': 0.5912186503410339, 'step': 244},\n",
       "  {'loss': 0.351872980594635, 'step': 245},\n",
       "  {'loss': 0.2542371451854706, 'step': 246},\n",
       "  {'loss': 0.30127865076065063, 'step': 247},\n",
       "  {'loss': 0.10335034132003784, 'step': 248},\n",
       "  {'loss': 0.2892921268939972, 'step': 249},\n",
       "  {'loss': 0.31962257623672485, 'step': 250},\n",
       "  {'loss': 0.9263043403625488, 'step': 251},\n",
       "  {'loss': 0.4315183758735657, 'step': 252},\n",
       "  {'loss': 0.4931502044200897, 'step': 253},\n",
       "  {'loss': 0.2611890733242035, 'step': 254},\n",
       "  {'loss': 0.33683913946151733, 'step': 255},\n",
       "  {'loss': 1.0662274360656738, 'step': 256},\n",
       "  {'loss': 0.7851182818412781, 'step': 257},\n",
       "  {'loss': 0.3890858292579651, 'step': 258},\n",
       "  {'loss': 0.38167503476142883, 'step': 259},\n",
       "  {'loss': 0.3451629877090454, 'step': 260},\n",
       "  {'loss': 0.15604601800441742, 'step': 261},\n",
       "  {'loss': 0.6492670178413391, 'step': 262},\n",
       "  {'loss': 0.2920037508010864, 'step': 263},\n",
       "  {'loss': 0.18286634981632233, 'step': 264},\n",
       "  {'loss': 0.2854951024055481, 'step': 265},\n",
       "  {'loss': 0.9570645093917847, 'step': 266},\n",
       "  {'loss': 0.49809861183166504, 'step': 267},\n",
       "  {'loss': 0.3848600685596466, 'step': 268},\n",
       "  {'loss': 0.2570047080516815, 'step': 269},\n",
       "  {'loss': 0.23530414700508118, 'step': 270},\n",
       "  {'loss': 0.1467982828617096, 'step': 271},\n",
       "  {'loss': 0.853691041469574, 'step': 272},\n",
       "  {'loss': 0.9653269648551941, 'step': 273},\n",
       "  {'loss': 0.5217640995979309, 'step': 274},\n",
       "  {'loss': 0.46581006050109863, 'step': 275},\n",
       "  {'loss': 0.4630581736564636, 'step': 276},\n",
       "  {'loss': 0.32104548811912537, 'step': 277},\n",
       "  {'loss': 0.14910876750946045, 'step': 278},\n",
       "  {'loss': 0.3384377360343933, 'step': 279},\n",
       "  {'loss': 0.7959123849868774, 'step': 280},\n",
       "  {'loss': 0.5146583318710327, 'step': 281},\n",
       "  {'loss': 0.5421584248542786, 'step': 282},\n",
       "  {'loss': 0.4200814366340637, 'step': 283},\n",
       "  {'loss': 0.4753284752368927, 'step': 284},\n",
       "  {'loss': 0.716428279876709, 'step': 285},\n",
       "  {'loss': 0.40390175580978394, 'step': 286},\n",
       "  {'loss': 0.2997485399246216, 'step': 287},\n",
       "  {'loss': 0.4051201343536377, 'step': 288},\n",
       "  {'loss': 0.22564449906349182, 'step': 289},\n",
       "  {'loss': 0.4921637773513794, 'step': 290},\n",
       "  {'loss': 0.22804151475429535, 'step': 291},\n",
       "  {'loss': 0.35193878412246704, 'step': 292},\n",
       "  {'loss': 1.3230342864990234, 'step': 293},\n",
       "  {'loss': 0.4602120518684387, 'step': 294},\n",
       "  {'loss': 0.25461289286613464, 'step': 295},\n",
       "  {'loss': 0.5274685621261597, 'step': 296},\n",
       "  {'loss': 0.24985608458518982, 'step': 297},\n",
       "  {'loss': 1.0715032815933228, 'step': 298},\n",
       "  {'loss': 0.28610244393348694, 'step': 299},\n",
       "  {'loss': 0.4595295488834381, 'step': 300},\n",
       "  {'loss': 0.36051827669143677, 'step': 301},\n",
       "  {'loss': 0.7749118208885193, 'step': 302},\n",
       "  {'loss': 0.2868722379207611, 'step': 303},\n",
       "  {'loss': 0.6884287595748901, 'step': 304},\n",
       "  {'loss': 0.3249971568584442, 'step': 305},\n",
       "  {'loss': 0.46122637391090393, 'step': 306},\n",
       "  {'loss': 1.0746946334838867, 'step': 307},\n",
       "  {'loss': 0.5127821564674377, 'step': 308},\n",
       "  {'loss': 0.39088642597198486, 'step': 309},\n",
       "  {'loss': 0.5942436456680298, 'step': 310},\n",
       "  {'loss': 0.18702438473701477, 'step': 311},\n",
       "  {'loss': 1.3138867616653442, 'step': 312},\n",
       "  {'loss': 0.3990021049976349, 'step': 313},\n",
       "  {'loss': 0.3254833519458771, 'step': 314},\n",
       "  {'loss': 0.3355690538883209, 'step': 315},\n",
       "  {'loss': 0.3677970767021179, 'step': 316},\n",
       "  {'loss': 0.23811885714530945, 'step': 317},\n",
       "  {'loss': 0.5500147938728333, 'step': 318},\n",
       "  {'loss': 0.5236992835998535, 'step': 319},\n",
       "  {'loss': 0.450994074344635, 'step': 320},\n",
       "  {'loss': 0.31193795800209045, 'step': 321},\n",
       "  {'loss': 0.41274088621139526, 'step': 322},\n",
       "  {'loss': 0.5728076100349426, 'step': 323},\n",
       "  {'loss': 0.5169793367385864, 'step': 324},\n",
       "  {'loss': 0.2321823686361313, 'step': 325},\n",
       "  {'loss': 0.3189956247806549, 'step': 326},\n",
       "  {'loss': 0.5823537707328796, 'step': 327},\n",
       "  {'loss': 0.28937584161758423, 'step': 328},\n",
       "  {'loss': 0.3322189450263977, 'step': 329},\n",
       "  {'loss': 0.13915574550628662, 'step': 330},\n",
       "  {'loss': 0.36480963230133057, 'step': 331},\n",
       "  {'loss': 0.24894484877586365, 'step': 332},\n",
       "  {'loss': 0.43698981404304504, 'step': 333},\n",
       "  {'loss': 0.5760581493377686, 'step': 334},\n",
       "  {'loss': 0.13805530965328217, 'step': 335},\n",
       "  {'loss': 0.5070580840110779, 'step': 336},\n",
       "  {'loss': 111.6017837524414, 'step': 337},\n",
       "  {'loss': 0.33813345432281494, 'step': 338},\n",
       "  {'loss': 0.9028794765472412, 'step': 339},\n",
       "  {'loss': 0.4704536199569702, 'step': 340},\n",
       "  {'loss': 0.6029374003410339, 'step': 341},\n",
       "  {'loss': 0.561066210269928, 'step': 342},\n",
       "  {'loss': 0.9372759461402893, 'step': 343},\n",
       "  {'loss': 1.0654951333999634, 'step': 344},\n",
       "  {'loss': 1.0665374994277954, 'step': 345},\n",
       "  {'loss': 2.3183300495147705, 'step': 346},\n",
       "  {'loss': 0.6663528680801392, 'step': 347},\n",
       "  {'loss': 0.836944580078125, 'step': 348},\n",
       "  {'loss': 0.6991577744483948, 'step': 349},\n",
       "  {'loss': 0.9173541069030762, 'step': 350},\n",
       "  {'loss': 0.8474465608596802, 'step': 351},\n",
       "  {'loss': 4.073408126831055, 'step': 352},\n",
       "  {'loss': 1.135230302810669, 'step': 353},\n",
       "  {'loss': 0.8918675184249878, 'step': 354},\n",
       "  {'loss': 0.8189195990562439, 'step': 355},\n",
       "  {'loss': 0.775926947593689, 'step': 356},\n",
       "  {'loss': 0.8393318057060242, 'step': 357},\n",
       "  {'loss': 0.40469038486480713, 'step': 358},\n",
       "  {'loss': 0.41310179233551025, 'step': 359},\n",
       "  {'loss': 0.823871374130249, 'step': 360},\n",
       "  {'loss': 0.7772927284240723, 'step': 361},\n",
       "  {'loss': 0.6588496565818787, 'step': 362},\n",
       "  {'loss': 0.6044597625732422, 'step': 363},\n",
       "  {'loss': 1.535617470741272, 'step': 364},\n",
       "  {'loss': 0.3913397192955017, 'step': 365},\n",
       "  {'loss': 0.553772509098053, 'step': 366},\n",
       "  {'loss': 0.9102449417114258, 'step': 367},\n",
       "  {'loss': 0.7212821841239929, 'step': 368},\n",
       "  {'loss': 0.7001287937164307, 'step': 369},\n",
       "  {'loss': 0.8608989119529724, 'step': 370},\n",
       "  {'loss': 0.6886849403381348, 'step': 371},\n",
       "  {'loss': 0.9561337232589722, 'step': 372},\n",
       "  {'loss': 0.4783019721508026, 'step': 373},\n",
       "  {'loss': 0.29503464698791504, 'step': 374},\n",
       "  {'loss': 0.34067651629447937, 'step': 375},\n",
       "  {'loss': 0.29647350311279297, 'step': 376},\n",
       "  {'loss': 1.0747406482696533, 'step': 377},\n",
       "  {'loss': 0.9431977272033691, 'step': 378},\n",
       "  {'loss': 0.8418216109275818, 'step': 379},\n",
       "  {'loss': 0.5352500081062317, 'step': 380},\n",
       "  {'loss': 1.2862080335617065, 'step': 381},\n",
       "  {'loss': 0.18622218072414398, 'step': 382},\n",
       "  {'loss': 0.3006579875946045, 'step': 383},\n",
       "  {'loss': 1.0446538925170898, 'step': 384},\n",
       "  {'loss': 0.6496981382369995, 'step': 385},\n",
       "  {'loss': 0.5318348407745361, 'step': 386},\n",
       "  {'loss': 0.625769317150116, 'step': 387},\n",
       "  {'loss': 0.374867707490921, 'step': 388},\n",
       "  {'loss': 0.33684760332107544, 'step': 389},\n",
       "  {'loss': 0.677245020866394, 'step': 390},\n",
       "  {'loss': 1.069960355758667, 'step': 391},\n",
       "  {'loss': 0.3022088408470154, 'step': 392},\n",
       "  {'loss': 0.5956515669822693, 'step': 393},\n",
       "  {'loss': 0.4102523922920227, 'step': 394},\n",
       "  {'loss': 0.4887767434120178, 'step': 395},\n",
       "  {'loss': 0.4964669346809387, 'step': 396},\n",
       "  {'loss': 0.46919119358062744, 'step': 397},\n",
       "  {'loss': 0.5387076139450073, 'step': 398},\n",
       "  {'loss': 0.3421817421913147, 'step': 399},\n",
       "  {'loss': 0.4968891143798828, 'step': 400},\n",
       "  {'loss': 0.5982121825218201, 'step': 401},\n",
       "  {'loss': 0.34759384393692017, 'step': 402},\n",
       "  {'loss': 0.2533576786518097, 'step': 403},\n",
       "  {'loss': 0.33284860849380493, 'step': 404},\n",
       "  {'loss': 1.0833439826965332, 'step': 405},\n",
       "  {'loss': 0.5277312397956848, 'step': 406},\n",
       "  {'loss': 0.36661481857299805, 'step': 407},\n",
       "  {'loss': 0.16588789224624634, 'step': 408},\n",
       "  {'loss': 0.17449507117271423, 'step': 409},\n",
       "  {'loss': 0.34462493658065796, 'step': 410},\n",
       "  {'loss': 0.4705928862094879, 'step': 411},\n",
       "  {'loss': 0.22018839418888092, 'step': 412},\n",
       "  {'loss': 0.32461217045783997, 'step': 413},\n",
       "  {'loss': 0.13742566108703613, 'step': 414},\n",
       "  {'loss': 0.3654046654701233, 'step': 415},\n",
       "  {'loss': 0.3125939965248108, 'step': 416},\n",
       "  {'loss': 0.3785800039768219, 'step': 417},\n",
       "  {'loss': 0.3123931884765625, 'step': 418},\n",
       "  {'loss': 0.16155731678009033, 'step': 419},\n",
       "  {'loss': 0.18661072850227356, 'step': 420},\n",
       "  {'loss': 0.20159174501895905, 'step': 421},\n",
       "  {'loss': 0.472354918718338, 'step': 422},\n",
       "  {'loss': 0.1738465279340744, 'step': 423},\n",
       "  {'loss': 0.3180767595767975, 'step': 424},\n",
       "  {'loss': 0.4660549461841583, 'step': 425},\n",
       "  {'loss': 0.4112667441368103, 'step': 426},\n",
       "  {'loss': 0.4877128303050995, 'step': 427},\n",
       "  {'loss': 0.15721167623996735, 'step': 428},\n",
       "  {'loss': 0.6927956938743591, 'step': 429},\n",
       "  {'loss': 0.3141028583049774, 'step': 430},\n",
       "  {'loss': 0.2428211122751236, 'step': 431},\n",
       "  {'loss': 0.3496720492839813, 'step': 432},\n",
       "  {'loss': 0.29670968651771545, 'step': 433},\n",
       "  {'loss': 1.1219332218170166, 'step': 434},\n",
       "  {'loss': 0.5363694429397583, 'step': 435},\n",
       "  {'loss': 0.20655304193496704, 'step': 436},\n",
       "  {'loss': 0.6314484477043152, 'step': 437},\n",
       "  {'loss': 0.8576227426528931, 'step': 438},\n",
       "  {'loss': 0.4518647789955139, 'step': 439},\n",
       "  {'loss': 0.17828233540058136, 'step': 440},\n",
       "  {'loss': 0.39897772669792175, 'step': 441},\n",
       "  {'loss': 0.559994637966156, 'step': 442},\n",
       "  {'loss': 0.5465084910392761, 'step': 443},\n",
       "  {'loss': 0.3718774914741516, 'step': 444},\n",
       "  {'loss': 0.9872440099716187, 'step': 445},\n",
       "  {'loss': 0.6743580102920532, 'step': 446},\n",
       "  {'loss': 0.7277695536613464, 'step': 447},\n",
       "  {'loss': 0.9163820743560791, 'step': 448},\n",
       "  {'loss': 0.4860643148422241, 'step': 449},\n",
       "  {'loss': 0.7056025266647339, 'step': 450},\n",
       "  {'loss': 1.4228177070617676, 'step': 451},\n",
       "  {'loss': 0.3075253963470459, 'step': 452},\n",
       "  {'loss': 0.6180543899536133, 'step': 453},\n",
       "  {'loss': 0.27923715114593506, 'step': 454},\n",
       "  {'loss': 0.297036737203598, 'step': 455},\n",
       "  {'loss': 0.45368102192878723, 'step': 456},\n",
       "  {'loss': 0.4764828383922577, 'step': 457},\n",
       "  {'loss': 1.1766010522842407, 'step': 458},\n",
       "  {'loss': 0.6235774755477905, 'step': 459},\n",
       "  {'loss': 0.324467271566391, 'step': 460},\n",
       "  {'loss': 0.6175673604011536, 'step': 461},\n",
       "  {'loss': 0.32331106066703796, 'step': 462},\n",
       "  {'loss': 0.4503173828125, 'step': 463},\n",
       "  {'loss': 0.28386178612709045, 'step': 464},\n",
       "  {'loss': 0.42535439133644104, 'step': 465},\n",
       "  {'loss': 0.38107091188430786, 'step': 466},\n",
       "  {'loss': 0.35177621245384216, 'step': 467},\n",
       "  {'loss': 0.3574642539024353, 'step': 468},\n",
       "  {'loss': 1.0005549192428589, 'step': 469},\n",
       "  {'loss': 0.5052984356880188, 'step': 470},\n",
       "  {'loss': 0.3076484501361847, 'step': 471},\n",
       "  {'loss': 0.6886504888534546, 'step': 472},\n",
       "  {'loss': 0.2037007212638855, 'step': 473},\n",
       "  {'loss': 0.3036574721336365, 'step': 474},\n",
       "  {'loss': 0.3017483353614807, 'step': 475},\n",
       "  {'loss': 0.4767628610134125, 'step': 476},\n",
       "  {'loss': 0.3607963025569916, 'step': 477},\n",
       "  {'loss': 0.23748953640460968, 'step': 478},\n",
       "  {'loss': 0.2201511561870575, 'step': 479},\n",
       "  {'loss': 0.7160157561302185, 'step': 480},\n",
       "  {'loss': 0.11744878441095352, 'step': 481},\n",
       "  {'loss': 0.345437228679657, 'step': 482},\n",
       "  {'loss': 0.11228387802839279, 'step': 483},\n",
       "  {'loss': 0.5549615621566772, 'step': 484},\n",
       "  {'loss': 0.2950636148452759, 'step': 485},\n",
       "  {'loss': 0.4096851348876953, 'step': 486},\n",
       "  {'loss': 0.15184839069843292, 'step': 487},\n",
       "  {'loss': 0.47851118445396423, 'step': 488},\n",
       "  {'loss': 0.10344815999269485, 'step': 489},\n",
       "  {'loss': 0.25204604864120483, 'step': 490},\n",
       "  {'loss': 0.49956512451171875, 'step': 491},\n",
       "  {'loss': 0.5737102627754211, 'step': 492},\n",
       "  {'loss': 0.2801875174045563, 'step': 493},\n",
       "  {'loss': 0.24614496529102325, 'step': 494},\n",
       "  {'loss': 0.6060659289360046, 'step': 495},\n",
       "  {'loss': 0.5351015329360962, 'step': 496},\n",
       "  {'loss': 0.168434739112854, 'step': 497},\n",
       "  {'loss': 0.43816956877708435, 'step': 498},\n",
       "  {'loss': 0.5645953416824341, 'step': 499},\n",
       "  {'loss': 0.3276837468147278, 'step': 500},\n",
       "  {'loss': 0.8499916791915894, 'step': 501},\n",
       "  {'loss': 0.221269428730011, 'step': 502},\n",
       "  {'loss': 0.5199622511863708, 'step': 503},\n",
       "  {'loss': 0.4724869132041931, 'step': 504},\n",
       "  {'loss': 0.22760853171348572, 'step': 505},\n",
       "  {'loss': 0.5654650330543518, 'step': 506},\n",
       "  {'loss': 0.42833563685417175, 'step': 507},\n",
       "  {'loss': 0.23880121111869812, 'step': 508},\n",
       "  {'loss': 0.6547080874443054, 'step': 509},\n",
       "  {'loss': 0.4411976635456085, 'step': 510},\n",
       "  {'loss': 0.13806937634944916, 'step': 511},\n",
       "  {'loss': 0.45091453194618225, 'step': 512},\n",
       "  {'loss': 0.49514612555503845, 'step': 513},\n",
       "  {'loss': 0.3910984694957733, 'step': 514},\n",
       "  {'loss': 0.5153918266296387, 'step': 515},\n",
       "  {'loss': 0.24711909890174866, 'step': 516},\n",
       "  {'loss': 1.285735011100769, 'step': 517},\n",
       "  {'loss': 0.264194130897522, 'step': 518},\n",
       "  {'loss': 0.2715334892272949, 'step': 519},\n",
       "  {'loss': 0.6801273226737976, 'step': 520},\n",
       "  {'loss': 0.17271378636360168, 'step': 521},\n",
       "  {'loss': 0.17493903636932373, 'step': 522},\n",
       "  {'loss': 0.3936014473438263, 'step': 523},\n",
       "  {'loss': 0.42510637640953064, 'step': 524},\n",
       "  {'loss': 0.34947216510772705, 'step': 525},\n",
       "  {'loss': 0.32392239570617676, 'step': 526},\n",
       "  {'loss': 0.16206541657447815, 'step': 527},\n",
       "  {'loss': 0.32350602746009827, 'step': 528},\n",
       "  {'loss': 0.16653652489185333, 'step': 529},\n",
       "  {'loss': 0.33797159790992737, 'step': 530},\n",
       "  {'loss': 0.578196108341217, 'step': 531},\n",
       "  {'loss': 0.7062675952911377, 'step': 532},\n",
       "  {'loss': 0.2806967496871948, 'step': 533},\n",
       "  {'loss': 0.5130430459976196, 'step': 534},\n",
       "  {'loss': 0.2982560992240906, 'step': 535},\n",
       "  {'loss': 0.2429034262895584, 'step': 536},\n",
       "  {'loss': 0.5587594509124756, 'step': 537},\n",
       "  {'loss': 0.5414720773696899, 'step': 538},\n",
       "  {'loss': 0.48120659589767456, 'step': 539},\n",
       "  {'loss': 0.5781181454658508, 'step': 540},\n",
       "  {'loss': 0.13072864711284637, 'step': 541},\n",
       "  {'loss': 0.45478901267051697, 'step': 542},\n",
       "  {'loss': 0.3549171984195709, 'step': 543},\n",
       "  {'loss': 0.8939645290374756, 'step': 544},\n",
       "  {'loss': 0.18461892008781433, 'step': 545},\n",
       "  {'loss': 0.2726203501224518, 'step': 546},\n",
       "  {'loss': 0.1915852427482605, 'step': 547},\n",
       "  {'loss': 0.5379149317741394, 'step': 548},\n",
       "  {'loss': 0.6133525371551514, 'step': 549},\n",
       "  {'loss': 0.30004969239234924, 'step': 550},\n",
       "  {'loss': 0.18608568608760834, 'step': 551},\n",
       "  {'loss': 0.3205924332141876, 'step': 552},\n",
       "  {'loss': 0.3951183557510376, 'step': 553},\n",
       "  {'loss': 0.40215909481048584, 'step': 554},\n",
       "  {'loss': 0.4696132242679596, 'step': 555},\n",
       "  {'loss': 0.3411804139614105, 'step': 556},\n",
       "  {'loss': 0.6463587880134583, 'step': 557},\n",
       "  {'loss': 0.6089003086090088, 'step': 558},\n",
       "  {'loss': 0.5739326477050781, 'step': 559},\n",
       "  {'loss': 0.36574888229370117, 'step': 560},\n",
       "  {'loss': 0.48582231998443604, 'step': 561},\n",
       "  {'loss': 0.2512689232826233, 'step': 562},\n",
       "  {'loss': 0.7014071941375732, 'step': 563},\n",
       "  {'loss': 0.4685569405555725, 'step': 564},\n",
       "  {'loss': 0.18905042111873627, 'step': 565},\n",
       "  {'loss': 0.8186110854148865, 'step': 566},\n",
       "  {'loss': 0.33221784234046936, 'step': 567},\n",
       "  {'loss': 1.3801615238189697, 'step': 568},\n",
       "  {'loss': 0.4587361216545105, 'step': 569},\n",
       "  {'loss': 0.30434244871139526, 'step': 570},\n",
       "  {'loss': 0.18754981458187103, 'step': 571},\n",
       "  {'loss': 0.3757880926132202, 'step': 572},\n",
       "  {'loss': 0.21254247426986694, 'step': 573},\n",
       "  {'loss': 0.5087500810623169, 'step': 574},\n",
       "  {'loss': 0.2809429466724396, 'step': 575},\n",
       "  {'loss': 0.7888950109481812, 'step': 576},\n",
       "  {'loss': 0.5949661135673523, 'step': 577},\n",
       "  {'loss': 0.9420610070228577, 'step': 578},\n",
       "  {'loss': 0.1727433055639267, 'step': 579},\n",
       "  {'loss': 0.30442875623703003, 'step': 580},\n",
       "  {'loss': 0.2531895637512207, 'step': 581},\n",
       "  {'loss': 0.09378144145011902, 'step': 582},\n",
       "  {'loss': 0.23894116282463074, 'step': 583},\n",
       "  {'loss': 0.21509648859500885, 'step': 584},\n",
       "  {'loss': 0.37855595350265503, 'step': 585},\n",
       "  {'loss': 0.4345967769622803, 'step': 586},\n",
       "  {'loss': 0.3183058500289917, 'step': 587},\n",
       "  {'loss': 0.44983574748039246, 'step': 588},\n",
       "  {'loss': 0.28028440475463867, 'step': 589},\n",
       "  {'loss': 0.4329532980918884, 'step': 590},\n",
       "  {'loss': 0.4412379860877991, 'step': 591},\n",
       "  {'loss': 0.6213427186012268, 'step': 592},\n",
       "  {'loss': 0.36245426535606384, 'step': 593},\n",
       "  {'loss': 0.21738287806510925, 'step': 594},\n",
       "  {'loss': 0.5916672348976135, 'step': 595},\n",
       "  {'loss': 0.278274804353714, 'step': 596},\n",
       "  {'loss': 0.3934865891933441, 'step': 597},\n",
       "  {'loss': 0.20762377977371216, 'step': 598},\n",
       "  {'loss': 0.6274399161338806, 'step': 599},\n",
       "  {'loss': 0.15507757663726807, 'step': 600},\n",
       "  {'loss': 0.43173715472221375, 'step': 601},\n",
       "  {'loss': 0.37820205092430115, 'step': 602},\n",
       "  {'loss': 0.20756201446056366, 'step': 603},\n",
       "  {'loss': 0.2601420283317566, 'step': 604},\n",
       "  {'loss': 0.23835539817810059, 'step': 605},\n",
       "  {'loss': 0.9012612104415894, 'step': 606},\n",
       "  {'loss': 0.4599614441394806, 'step': 607},\n",
       "  {'loss': 0.453002393245697, 'step': 608},\n",
       "  {'loss': 0.34941115975379944, 'step': 609},\n",
       "  {'loss': 0.3155340850353241, 'step': 610},\n",
       "  {'loss': 0.5209740400314331, 'step': 611},\n",
       "  {'loss': 1.5242489576339722, 'step': 612},\n",
       "  {'loss': 0.39677369594573975, 'step': 613},\n",
       "  {'loss': 0.4767361581325531, 'step': 614},\n",
       "  {'loss': 0.3962482511997223, 'step': 615},\n",
       "  {'loss': 0.1349031627178192, 'step': 616},\n",
       "  {'loss': 0.44762927293777466, 'step': 617},\n",
       "  {'loss': 0.3553725481033325, 'step': 618},\n",
       "  {'loss': 0.347307026386261, 'step': 619},\n",
       "  {'loss': 0.9953462481498718, 'step': 620},\n",
       "  {'loss': 0.6326065063476562, 'step': 621},\n",
       "  {'loss': 0.4008665680885315, 'step': 622},\n",
       "  {'loss': 0.18196892738342285, 'step': 623},\n",
       "  {'loss': 0.9500423669815063, 'step': 624},\n",
       "  {'loss': 0.519071102142334, 'step': 625},\n",
       "  {'loss': 0.46308496594429016, 'step': 626},\n",
       "  {'loss': 0.3746754825115204, 'step': 627},\n",
       "  {'loss': 0.29941874742507935, 'step': 628},\n",
       "  {'loss': 0.3059564232826233, 'step': 629},\n",
       "  {'loss': 0.2387826293706894, 'step': 630},\n",
       "  {'loss': 0.8940079212188721, 'step': 631},\n",
       "  {'loss': 1.6182595491409302, 'step': 632},\n",
       "  {'loss': 0.5141507387161255, 'step': 633},\n",
       "  {'loss': 0.362368106842041, 'step': 634},\n",
       "  {'loss': 0.6442926526069641, 'step': 635},\n",
       "  {'loss': 0.327653169631958, 'step': 636},\n",
       "  {'loss': 0.2759366035461426, 'step': 637},\n",
       "  {'loss': 0.3255065977573395, 'step': 638},\n",
       "  {'loss': 1.469516396522522, 'step': 639},\n",
       "  {'loss': 0.7155097126960754, 'step': 640},\n",
       "  {'loss': 0.15967155992984772, 'step': 641},\n",
       "  {'loss': 0.5013645887374878, 'step': 642},\n",
       "  {'loss': 0.5479186773300171, 'step': 643},\n",
       "  {'loss': 0.5333529114723206, 'step': 644},\n",
       "  {'loss': 0.49652159214019775, 'step': 645},\n",
       "  {'loss': 0.4301879405975342, 'step': 646},\n",
       "  {'loss': 0.4797161817550659, 'step': 647},\n",
       "  {'loss': 0.22829264402389526, 'step': 648},\n",
       "  {'loss': 0.312113881111145, 'step': 649},\n",
       "  {'loss': 0.20212402939796448, 'step': 650},\n",
       "  {'loss': 0.2946337163448334, 'step': 651},\n",
       "  {'loss': 0.41258615255355835, 'step': 652},\n",
       "  {'loss': 0.12402620911598206, 'step': 653},\n",
       "  {'loss': 0.3324732780456543, 'step': 654},\n",
       "  {'loss': 0.3150087296962738, 'step': 655},\n",
       "  {'loss': 0.830931544303894, 'step': 656},\n",
       "  {'loss': 0.30487778782844543, 'step': 657},\n",
       "  {'loss': 0.3133031725883484, 'step': 658},\n",
       "  {'loss': 0.6713010668754578, 'step': 659},\n",
       "  {'loss': 0.4882768392562866, 'step': 660},\n",
       "  {'loss': 0.09175247699022293, 'step': 661},\n",
       "  {'loss': 0.5257484912872314, 'step': 662},\n",
       "  {'loss': 0.162136971950531, 'step': 663},\n",
       "  {'loss': 0.16762270033359528, 'step': 664},\n",
       "  {'loss': 0.4248811602592468, 'step': 665},\n",
       "  {'loss': 0.27196624875068665, 'step': 666},\n",
       "  {'loss': 0.6258731484413147, 'step': 667},\n",
       "  {'loss': 0.3647388815879822, 'step': 668},\n",
       "  {'loss': 0.7494158148765564, 'step': 669},\n",
       "  {'loss': 0.4411829710006714, 'step': 670},\n",
       "  {'loss': 0.3715357184410095, 'step': 671},\n",
       "  {'loss': 0.538206934928894, 'step': 672},\n",
       "  {'loss': 0.6551802158355713, 'step': 673},\n",
       "  {'loss': 0.35268667340278625, 'step': 674},\n",
       "  {'loss': 0.4624295234680176, 'step': 675},\n",
       "  {'loss': 0.2450980544090271, 'step': 676},\n",
       "  {'loss': 0.28185680508613586, 'step': 677},\n",
       "  {'loss': 0.30691608786582947, 'step': 678},\n",
       "  {'loss': 0.5392729043960571, 'step': 679},\n",
       "  {'loss': 0.13724583387374878, 'step': 680},\n",
       "  {'loss': 0.31009143590927124, 'step': 681},\n",
       "  {'loss': 0.34216591715812683, 'step': 682},\n",
       "  {'loss': 0.4323790669441223, 'step': 683},\n",
       "  {'loss': 0.1679183393716812, 'step': 684},\n",
       "  {'loss': 0.2040388435125351, 'step': 685},\n",
       "  {'loss': 0.24732732772827148, 'step': 686},\n",
       "  {'loss': 0.7831516861915588, 'step': 687},\n",
       "  {'loss': 0.4202706813812256, 'step': 688},\n",
       "  {'loss': 0.45275193452835083, 'step': 689},\n",
       "  {'loss': 0.32372817397117615, 'step': 690},\n",
       "  {'loss': 0.4976375102996826, 'step': 691},\n",
       "  {'loss': 0.25030744075775146, 'step': 692},\n",
       "  {'loss': 0.3803889751434326, 'step': 693},\n",
       "  {'loss': 0.4554414749145508, 'step': 694},\n",
       "  {'loss': 0.47824814915657043, 'step': 695},\n",
       "  {'loss': 0.12180867791175842, 'step': 696},\n",
       "  {'loss': 0.12969544529914856, 'step': 697},\n",
       "  {'loss': 0.2599489986896515, 'step': 698},\n",
       "  {'loss': 0.5709814429283142, 'step': 699},\n",
       "  {'loss': 0.3736425042152405, 'step': 700},\n",
       "  {'loss': 0.09650402516126633, 'step': 701},\n",
       "  {'loss': 0.21523606777191162, 'step': 702},\n",
       "  {'loss': 0.3022991120815277, 'step': 703},\n",
       "  {'loss': 0.1489589512348175, 'step': 704},\n",
       "  {'loss': 0.4587710201740265, 'step': 705},\n",
       "  {'loss': 0.45209410786628723, 'step': 706},\n",
       "  {'loss': 0.20871958136558533, 'step': 707},\n",
       "  {'loss': 0.4485853612422943, 'step': 708},\n",
       "  {'loss': 0.4508308470249176, 'step': 709},\n",
       "  {'loss': 0.28446081280708313, 'step': 710},\n",
       "  {'loss': 0.41943907737731934, 'step': 711},\n",
       "  {'loss': 0.3057781457901001, 'step': 712},\n",
       "  {'loss': 0.6743127107620239, 'step': 713},\n",
       "  {'loss': 0.6475483179092407, 'step': 714},\n",
       "  {'loss': 2.7629451751708984, 'step': 715},\n",
       "  {'loss': 0.5002732872962952, 'step': 716},\n",
       "  {'loss': 0.09605450928211212, 'step': 717},\n",
       "  {'loss': 0.6922814249992371, 'step': 718},\n",
       "  {'loss': 0.07341697812080383, 'step': 719},\n",
       "  {'loss': 0.15283633768558502, 'step': 720},\n",
       "  {'loss': 0.4287618398666382, 'step': 721},\n",
       "  {'loss': 0.4114938974380493, 'step': 722},\n",
       "  {'loss': 0.3019053339958191, 'step': 723},\n",
       "  {'loss': 0.883080005645752, 'step': 724},\n",
       "  {'loss': 1.2423311471939087, 'step': 725},\n",
       "  {'loss': 0.37559762597084045, 'step': 726},\n",
       "  {'loss': 0.3607962131500244, 'step': 727},\n",
       "  {'loss': 0.43187475204467773, 'step': 728},\n",
       "  {'loss': 0.47533851861953735, 'step': 729},\n",
       "  {'loss': 0.683596134185791, 'step': 730},\n",
       "  {'loss': 0.2601480782032013, 'step': 731},\n",
       "  {'loss': 0.47054538130760193, 'step': 732},\n",
       "  {'loss': 0.813991904258728, 'step': 733},\n",
       "  {'loss': 1.165379285812378, 'step': 734},\n",
       "  {'loss': 0.5394524335861206, 'step': 735},\n",
       "  {'loss': 0.34240052103996277, 'step': 736},\n",
       "  {'loss': 0.32659509778022766, 'step': 737},\n",
       "  {'loss': 1.2600157260894775, 'step': 738},\n",
       "  {'loss': 0.2786130905151367, 'step': 739},\n",
       "  {'loss': 0.23651725053787231, 'step': 740},\n",
       "  {'loss': 0.11376632750034332, 'step': 741},\n",
       "  {'loss': 1.0362536907196045, 'step': 742},\n",
       "  {'loss': 0.2430965155363083, 'step': 743},\n",
       "  {'loss': 0.19654633104801178, 'step': 744},\n",
       "  {'loss': 0.5360729098320007, 'step': 745},\n",
       "  {'loss': 0.41471797227859497, 'step': 746},\n",
       "  {'loss': 0.3732227087020874, 'step': 747},\n",
       "  {'loss': 0.8474633097648621, 'step': 748},\n",
       "  {'loss': 0.2707872688770294, 'step': 749},\n",
       "  {'loss': 0.340911328792572, 'step': 750},\n",
       "  {'loss': 0.2524482011795044, 'step': 751},\n",
       "  {'loss': 0.7763667106628418, 'step': 752},\n",
       "  {'loss': 0.42425474524497986, 'step': 753},\n",
       "  {'loss': 0.35715240240097046, 'step': 754},\n",
       "  {'loss': 1.0049586296081543, 'step': 755},\n",
       "  {'loss': 0.2693817615509033, 'step': 756},\n",
       "  {'loss': 0.21344256401062012, 'step': 757},\n",
       "  {'loss': 0.14313577115535736, 'step': 758},\n",
       "  {'loss': 0.3934306204319, 'step': 759},\n",
       "  {'loss': 0.572108268737793, 'step': 760},\n",
       "  {'loss': 0.3377494812011719, 'step': 761},\n",
       "  {'loss': 0.5040553212165833, 'step': 762},\n",
       "  {'loss': 0.28962719440460205, 'step': 763},\n",
       "  {'loss': 0.37142252922058105, 'step': 764},\n",
       "  {'loss': 0.5233190655708313, 'step': 765},\n",
       "  {'loss': 0.5916100144386292, 'step': 766},\n",
       "  {'loss': 0.10012064129114151, 'step': 767},\n",
       "  {'loss': 0.3945804834365845, 'step': 768},\n",
       "  {'loss': 0.3334602415561676, 'step': 769},\n",
       "  {'loss': 0.181845560669899, 'step': 770},\n",
       "  {'loss': 0.17673781514167786, 'step': 771},\n",
       "  {'loss': 0.603908896446228, 'step': 772},\n",
       "  {'loss': 0.44192051887512207, 'step': 773},\n",
       "  {'loss': 0.43434253334999084, 'step': 774},\n",
       "  {'loss': 0.45112234354019165, 'step': 775},\n",
       "  {'loss': 0.4572157859802246, 'step': 776},\n",
       "  {'loss': 0.3588992953300476, 'step': 777},\n",
       "  {'loss': 0.7622118592262268, 'step': 778},\n",
       "  {'loss': 0.3261232078075409, 'step': 779},\n",
       "  {'loss': 0.1778402328491211, 'step': 780},\n",
       "  {'loss': 0.2888525724411011, 'step': 781},\n",
       "  {'loss': 0.24286480247974396, 'step': 782},\n",
       "  {'loss': 0.5665422677993774, 'step': 783},\n",
       "  {'loss': 0.4632648229598999, 'step': 784},\n",
       "  {'loss': 0.3450808823108673, 'step': 785},\n",
       "  {'loss': 1.4458367824554443, 'step': 786},\n",
       "  {'loss': 0.2334803342819214, 'step': 787},\n",
       "  {'loss': 0.5863394737243652, 'step': 788},\n",
       "  {'loss': 0.17883038520812988, 'step': 789},\n",
       "  {'loss': 0.21850073337554932, 'step': 790},\n",
       "  {'loss': 0.12360547482967377, 'step': 791},\n",
       "  {'loss': 0.38126814365386963, 'step': 792},\n",
       "  {'loss': 0.27856501936912537, 'step': 793},\n",
       "  {'loss': 0.8965135216712952, 'step': 794},\n",
       "  {'loss': 0.6887660026550293, 'step': 795},\n",
       "  {'loss': 0.9392605423927307, 'step': 796},\n",
       "  {'loss': 0.4573761820793152, 'step': 797},\n",
       "  {'loss': 0.16086165606975555, 'step': 798},\n",
       "  {'loss': 0.14183317124843597, 'step': 799},\n",
       "  {'loss': 0.3656470775604248, 'step': 800},\n",
       "  {'loss': 0.19004929065704346, 'step': 801},\n",
       "  {'loss': 0.2839648127555847, 'step': 802},\n",
       "  {'loss': 0.17350026965141296, 'step': 803},\n",
       "  {'loss': 0.7528149485588074, 'step': 804},\n",
       "  {'loss': 0.25341618061065674, 'step': 805},\n",
       "  {'loss': 0.19139382243156433, 'step': 806},\n",
       "  {'loss': 0.4290325939655304, 'step': 807},\n",
       "  {'loss': 0.38728055357933044, 'step': 808},\n",
       "  {'loss': 0.4188617169857025, 'step': 809},\n",
       "  {'loss': 0.310564249753952, 'step': 810},\n",
       "  {'loss': 0.10946206748485565, 'step': 811},\n",
       "  {'loss': 0.4020195007324219, 'step': 812},\n",
       "  {'loss': 0.1818273514509201, 'step': 813},\n",
       "  {'loss': 0.2671203911304474, 'step': 814},\n",
       "  {'loss': 0.42854079604148865, 'step': 815},\n",
       "  {'loss': 0.22130359709262848, 'step': 816},\n",
       "  {'loss': 0.5672789216041565, 'step': 817},\n",
       "  {'loss': 0.45536696910858154, 'step': 818},\n",
       "  {'loss': 0.14554157853126526, 'step': 819},\n",
       "  {'loss': 0.2204936444759369, 'step': 820},\n",
       "  {'loss': 0.3594576418399811, 'step': 821},\n",
       "  {'loss': 0.5377707481384277, 'step': 822},\n",
       "  {'loss': 0.3390558958053589, 'step': 823},\n",
       "  {'loss': 0.9748522639274597, 'step': 824},\n",
       "  {'loss': 0.17609934508800507, 'step': 825},\n",
       "  {'loss': 0.5026370286941528, 'step': 826},\n",
       "  {'loss': 0.26128798723220825, 'step': 827},\n",
       "  {'loss': 0.26529982686042786, 'step': 828},\n",
       "  {'loss': 0.5308712720870972, 'step': 829},\n",
       "  {'loss': 0.2588560879230499, 'step': 830},\n",
       "  {'loss': 0.46121811866760254, 'step': 831},\n",
       "  {'loss': 0.5885621309280396, 'step': 832},\n",
       "  {'loss': 0.4106628894805908, 'step': 833},\n",
       "  {'loss': 1.5248254537582397, 'step': 834},\n",
       "  {'loss': 0.5633256435394287, 'step': 835},\n",
       "  {'loss': 0.12411103397607803, 'step': 836},\n",
       "  {'loss': 0.2851852774620056, 'step': 837},\n",
       "  {'loss': 0.7527061700820923, 'step': 838},\n",
       "  {'loss': 0.22038614749908447, 'step': 839},\n",
       "  {'loss': 0.5465067028999329, 'step': 840},\n",
       "  {'loss': 0.6001733541488647, 'step': 841},\n",
       "  {'loss': 0.9093241095542908, 'step': 842},\n",
       "  {'loss': 0.1262221336364746, 'step': 843},\n",
       "  {'loss': 0.26889926195144653, 'step': 844},\n",
       "  {'loss': 0.5760403871536255, 'step': 845},\n",
       "  {'loss': 0.2626710832118988, 'step': 846},\n",
       "  {'loss': 0.5419657230377197, 'step': 847},\n",
       "  {'loss': 0.2388145923614502, 'step': 848},\n",
       "  {'loss': 0.46503889560699463, 'step': 849},\n",
       "  {'loss': 0.18897509574890137, 'step': 850},\n",
       "  {'loss': 0.4054734408855438, 'step': 851},\n",
       "  {'loss': 0.4643641710281372, 'step': 852},\n",
       "  {'loss': 0.3686690330505371, 'step': 853},\n",
       "  {'loss': 0.19236472249031067, 'step': 854},\n",
       "  {'loss': 0.3525269627571106, 'step': 855},\n",
       "  {'loss': 1.3481459617614746, 'step': 856},\n",
       "  {'loss': 0.33529239892959595, 'step': 857},\n",
       "  {'loss': 0.1605207622051239, 'step': 858},\n",
       "  {'loss': 0.24583184719085693, 'step': 859},\n",
       "  {'loss': 0.4809180796146393, 'step': 860},\n",
       "  {'loss': 0.18299424648284912, 'step': 861},\n",
       "  {'loss': 1.2900209426879883, 'step': 862},\n",
       "  {'loss': 0.14177381992340088, 'step': 863},\n",
       "  {'loss': 0.2352701872587204, 'step': 864},\n",
       "  {'loss': 0.25294339656829834, 'step': 865},\n",
       "  {'loss': 0.35580146312713623, 'step': 866},\n",
       "  {'loss': 0.22074447572231293, 'step': 867},\n",
       "  {'loss': 0.5518107414245605, 'step': 868},\n",
       "  {'loss': 0.4481164813041687, 'step': 869},\n",
       "  {'loss': 0.7418827414512634, 'step': 870},\n",
       "  {'loss': 0.6966396570205688, 'step': 871},\n",
       "  {'loss': 0.6343236565589905, 'step': 872},\n",
       "  {'loss': 0.20169341564178467, 'step': 873},\n",
       "  {'loss': 0.279360830783844, 'step': 874},\n",
       "  {'loss': 0.4900488257408142, 'step': 875},\n",
       "  {'loss': 0.49378901720046997, 'step': 876},\n",
       "  {'loss': 0.6919163465499878, 'step': 877},\n",
       "  {'loss': 1.6256476640701294, 'step': 878},\n",
       "  {'loss': 0.25230133533477783, 'step': 879},\n",
       "  {'loss': 0.4331289231777191, 'step': 880},\n",
       "  {'loss': 0.6185625791549683, 'step': 881},\n",
       "  {'loss': 0.47473740577697754, 'step': 882},\n",
       "  {'loss': 0.38444700837135315, 'step': 883},\n",
       "  {'loss': 0.3180197775363922, 'step': 884},\n",
       "  {'loss': 0.16197378933429718, 'step': 885},\n",
       "  {'loss': 0.36817166209220886, 'step': 886},\n",
       "  {'loss': 0.7595881223678589, 'step': 887},\n",
       "  {'loss': 0.2608256936073303, 'step': 888},\n",
       "  {'loss': 0.12029493600130081, 'step': 889},\n",
       "  {'loss': 0.3496663570404053, 'step': 890},\n",
       "  {'loss': 0.17382706701755524, 'step': 891},\n",
       "  {'loss': 0.5584269762039185, 'step': 892},\n",
       "  {'loss': 0.2772042751312256, 'step': 893},\n",
       "  {'loss': 0.5077247023582458, 'step': 894},\n",
       "  {'loss': 0.3454708755016327, 'step': 895},\n",
       "  {'loss': 1.294623851776123, 'step': 896},\n",
       "  {'loss': 0.30496370792388916, 'step': 897},\n",
       "  {'loss': 0.7194246649742126, 'step': 898},\n",
       "  {'loss': 0.2975522577762604, 'step': 899},\n",
       "  {'loss': 0.08799423277378082, 'step': 900},\n",
       "  {'loss': 0.6506577730178833, 'step': 901},\n",
       "  {'loss': 0.667636513710022, 'step': 902},\n",
       "  {'loss': 0.3814590573310852, 'step': 903},\n",
       "  {'loss': 0.15846949815750122, 'step': 904},\n",
       "  {'loss': 0.3952065110206604, 'step': 905},\n",
       "  {'loss': 0.5029269456863403, 'step': 906},\n",
       "  {'loss': 0.28354743123054504, 'step': 907},\n",
       "  {'loss': 0.5972546339035034, 'step': 908},\n",
       "  {'loss': 0.5695491433143616, 'step': 909},\n",
       "  {'loss': 0.2811940610408783, 'step': 910},\n",
       "  {'loss': 0.30209869146347046, 'step': 911},\n",
       "  {'loss': 0.37048494815826416, 'step': 912},\n",
       "  {'loss': 0.8827427625656128, 'step': 913},\n",
       "  {'loss': 0.30427733063697815, 'step': 914},\n",
       "  {'loss': 0.571792483329773, 'step': 915},\n",
       "  {'loss': 0.37339234352111816, 'step': 916},\n",
       "  {'loss': 0.282083660364151, 'step': 917},\n",
       "  {'loss': 0.29897430539131165, 'step': 918},\n",
       "  {'loss': 0.5114350318908691, 'step': 919},\n",
       "  {'loss': 0.3261116147041321, 'step': 920},\n",
       "  {'loss': 0.9467285871505737, 'step': 921},\n",
       "  {'loss': 0.3489034175872803, 'step': 922},\n",
       "  {'loss': 0.39370623230934143, 'step': 923},\n",
       "  {'loss': 0.527498722076416, 'step': 924},\n",
       "  {'loss': 0.09120891988277435, 'step': 925},\n",
       "  {'loss': 0.14315837621688843, 'step': 926},\n",
       "  {'loss': 0.6919458508491516, 'step': 927},\n",
       "  {'loss': 0.5406561493873596, 'step': 928},\n",
       "  {'loss': 0.5855380892753601, 'step': 929},\n",
       "  {'loss': 0.13397720456123352, 'step': 930},\n",
       "  {'loss': 0.6718964576721191, 'step': 931},\n",
       "  {'loss': 0.39583587646484375, 'step': 932},\n",
       "  {'loss': 0.6830822229385376, 'step': 933},\n",
       "  {'loss': 0.596707820892334, 'step': 934},\n",
       "  {'loss': 0.2413311004638672, 'step': 935},\n",
       "  {'loss': 0.5329327583312988, 'step': 936},\n",
       "  {'loss': 0.256255179643631, 'step': 937},\n",
       "  {'loss': 0.10874911397695541, 'step': 938},\n",
       "  {'loss': 0.12975837290287018, 'step': 939},\n",
       "  {'loss': 0.31047073006629944, 'step': 940},\n",
       "  {'loss': 0.46608519554138184, 'step': 941},\n",
       "  {'loss': 0.17376019060611725, 'step': 942},\n",
       "  {'loss': 0.4207985997200012, 'step': 943},\n",
       "  {'loss': 0.4505196511745453, 'step': 944},\n",
       "  {'loss': 0.4500388503074646, 'step': 945},\n",
       "  {'loss': 0.7560434341430664, 'step': 946},\n",
       "  {'loss': 0.1836225837469101, 'step': 947},\n",
       "  {'loss': 0.23109090328216553, 'step': 948},\n",
       "  {'loss': 0.12153452634811401, 'step': 949},\n",
       "  {'loss': 0.307137131690979, 'step': 950},\n",
       "  {'loss': 1.157355785369873, 'step': 951},\n",
       "  {'loss': 0.22093512117862701, 'step': 952},\n",
       "  {'loss': 0.35122260451316833, 'step': 953},\n",
       "  {'loss': 0.224482923746109, 'step': 954},\n",
       "  {'loss': 0.2937527000904083, 'step': 955},\n",
       "  {'loss': 0.35654935240745544, 'step': 956},\n",
       "  {'loss': 0.7082676887512207, 'step': 957},\n",
       "  {'loss': 0.4445984661579132, 'step': 958},\n",
       "  {'loss': 0.533492922782898, 'step': 959},\n",
       "  {'loss': 0.3862212598323822, 'step': 960},\n",
       "  {'loss': 0.26603758335113525, 'step': 961},\n",
       "  {'loss': 0.4244295060634613, 'step': 962},\n",
       "  {'loss': 0.19670595228672028, 'step': 963},\n",
       "  {'loss': 0.574733555316925, 'step': 964},\n",
       "  {'loss': 0.384860634803772, 'step': 965},\n",
       "  {'loss': 2.515584707260132, 'step': 966},\n",
       "  {'loss': 0.4015951454639435, 'step': 967},\n",
       "  {'loss': 0.3864823877811432, 'step': 968},\n",
       "  {'loss': 0.842566967010498, 'step': 969},\n",
       "  {'loss': 0.4763081967830658, 'step': 970},\n",
       "  {'loss': 0.2303977906703949, 'step': 971},\n",
       "  {'loss': 0.14806456863880157, 'step': 972},\n",
       "  {'loss': 0.19747014343738556, 'step': 973},\n",
       "  {'loss': 0.2713344395160675, 'step': 974},\n",
       "  {'loss': 0.6961697340011597, 'step': 975},\n",
       "  {'loss': 0.689001739025116, 'step': 976},\n",
       "  {'loss': 0.46932902932167053, 'step': 977},\n",
       "  {'loss': 0.4683806896209717, 'step': 978},\n",
       "  {'loss': 0.316445529460907, 'step': 979},\n",
       "  {'loss': 0.09897623211145401, 'step': 980},\n",
       "  {'loss': 0.32003000378608704, 'step': 981},\n",
       "  {'loss': 0.5625864267349243, 'step': 982},\n",
       "  {'loss': 0.32642728090286255, 'step': 983},\n",
       "  {'loss': 0.5832780003547668, 'step': 984},\n",
       "  {'loss': 0.08625727146863937, 'step': 985},\n",
       "  {'loss': 0.38520997762680054, 'step': 986},\n",
       "  {'loss': 0.16172848641872406, 'step': 987},\n",
       "  {'loss': 0.9868780374526978, 'step': 988},\n",
       "  {'loss': 0.397068053483963, 'step': 989},\n",
       "  {'loss': 0.7635108828544617, 'step': 990},\n",
       "  {'loss': 0.31784293055534363, 'step': 991},\n",
       "  {'loss': 0.34060782194137573, 'step': 992},\n",
       "  {'loss': 0.47793474793434143, 'step': 993},\n",
       "  {'loss': 0.45805785059928894, 'step': 994},\n",
       "  {'loss': 0.29712000489234924, 'step': 995},\n",
       "  {'loss': 0.5839395523071289, 'step': 996},\n",
       "  {'loss': 0.43675538897514343, 'step': 997},\n",
       "  {'loss': 0.2773881256580353, 'step': 998},\n",
       "  {'loss': 0.5102629065513611, 'step': 999},\n",
       "  ...],\n",
       " 'val': [{'loss': 4.873431015605769, 'step': 0},\n",
       "  {'loss': 0.4467209942392574, 'step': 726},\n",
       "  {'loss': 0.4250037178766629, 'step': 1452},\n",
       "  {'loss': 0.4032026431099935, 'step': 2178},\n",
       "  {'loss': 0.38448175526231776, 'step': 2904},\n",
       "  {'loss': 0.3851936950602315, 'step': 3630},\n",
       "  {'loss': 0.40908823719571447, 'step': 4356},\n",
       "  {'loss': 0.38351150812996815, 'step': 5082},\n",
       "  {'loss': 0.3740496376513942, 'step': 5808},\n",
       "  {'loss': 0.3719144913806649, 'step': 6534},\n",
       "  {'loss': 0.3623239483899814, 'step': 7260},\n",
       "  {'loss': 0.38474442869855846, 'step': 7986},\n",
       "  {'loss': 0.38110921131677866, 'step': 8712},\n",
       "  {'loss': 0.40198790574492504, 'step': 9438},\n",
       "  {'loss': 0.3840583742342212, 'step': 10164},\n",
       "  {'loss': 0.371404657278918, 'step': 10890},\n",
       "  {'loss': 0.3682406803916308, 'step': 11616},\n",
       "  {'loss': 0.36093294289548045, 'step': 12342},\n",
       "  {'loss': 0.3605957720890518, 'step': 13068},\n",
       "  {'loss': 0.3618034212118831, 'step': 13794},\n",
       "  {'loss': 0.356048348721517, 'step': 14520},\n",
       "  {'loss': 0.35075688706941843, 'step': 15246},\n",
       "  {'loss': 0.35877057608247787, 'step': 15972},\n",
       "  {'loss': 0.4064028339445098, 'step': 16698},\n",
       "  {'loss': 0.3549993550481875, 'step': 17424},\n",
       "  {'loss': 0.3534009079179488, 'step': 18150},\n",
       "  {'loss': 0.37378424453772296, 'step': 18876},\n",
       "  {'loss': 0.3502616899565232, 'step': 19602},\n",
       "  {'loss': 0.3602590339088982, 'step': 20328},\n",
       "  {'loss': 0.34758034585551784, 'step': 21054},\n",
       "  {'loss': 0.36177064592311203, 'step': 21780},\n",
       "  {'loss': 0.3458845202064465, 'step': 22506},\n",
       "  {'loss': 0.3477687401897159, 'step': 23232},\n",
       "  {'loss': 0.34422475433608224, 'step': 23958},\n",
       "  {'loss': 0.34900686057084357, 'step': 24684},\n",
       "  {'loss': 0.3467280819611855, 'step': 25410},\n",
       "  {'loss': 0.3346386582798455, 'step': 26136},\n",
       "  {'loss': 0.33609821447286725, 'step': 26862},\n",
       "  {'loss': 0.33107022334598313, 'step': 27588},\n",
       "  {'loss': 0.3317154318186616, 'step': 28314},\n",
       "  {'loss': 0.33797619816623936, 'step': 29040},\n",
       "  {'loss': 0.34245729886672716, 'step': 29766},\n",
       "  {'loss': 0.3280280810157376, 'step': 30492},\n",
       "  {'loss': 0.32698282705666115, 'step': 31218},\n",
       "  {'loss': 0.3265986284779862, 'step': 31944},\n",
       "  {'loss': 0.3287919202496198, 'step': 32670},\n",
       "  {'loss': 0.3237771071216538, 'step': 33396},\n",
       "  {'loss': 0.32387568926330934, 'step': 34122},\n",
       "  {'loss': 0.3237432038857917, 'step': 34848},\n",
       "  {'loss': 0.3297969411658354, 'step': 35574},\n",
       "  {'loss': 0.3763558439417811, 'step': 36300},\n",
       "  {'loss': 0.3290340173373784, 'step': 37026},\n",
       "  {'loss': 0.3285453823695252, 'step': 37752},\n",
       "  {'loss': 0.3286434639522359, 'step': 38478},\n",
       "  {'loss': 0.32756270697602063, 'step': 39204},\n",
       "  {'loss': 0.32419998860679383, 'step': 39930},\n",
       "  {'loss': 0.33243223808490296, 'step': 40656}]}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 19
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:27:08.555486Z",
     "start_time": "2025-02-05T07:27:08.495246Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "# 定义一个名为 plot_learning_curves 的函数，接受以下参数：\n",
    "# record_dict: 包含训练和验证记录的字典。\n",
    "# sample_step: 对训练数据进行采样的步长，默认值为 500。\n",
    "# 该函数用于可视化训练和验证过程中的性能指标。\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # 将训练记录转换为 Pandas DataFrame，并设置 step 列为索引。然后对数据进行采样，步长为 sample_step\n",
    "    # pd.DataFrame(record_dict[\"train\"]): 将训练记录转换为 DataFrame。\n",
    "    # .set_index(\"step\"): 将 step 列设置为索引。\n",
    "    # .iloc[::sample_step]: 对数据进行采样，每隔 sample_step 步取一个样本。\n",
    "    # 减少数据点的数量，使曲线更清晰，同时保留趋势\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "\n",
    "    # 将验证记录转换为 Pandas DataFrame，并设置 step 列为索引\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # 遍历训练 DataFrame 的每一列（即每个性能指标）。\n",
    "    # 使用 enumerate 获取列名和索引\n",
    "    for idx, item in enumerate(train_df.columns):\n",
    "        # train_df.index: x 轴数据（训练步数）。\n",
    "        # train_df[item]: y 轴数据（性能指标值）。\n",
    "        # label=f\"train_{item}\": 设置曲线的标签。\n",
    "        plt.plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        plt.plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "\n",
    "        plt.grid()  # 在当前子图上添加网格线\n",
    "        plt.legend()  # 在当前子图上添加图例\n",
    "\n",
    "        # 生成 x 轴的刻度数据，从 0 到最大步数，步长为 5000\n",
    "        x_data = range(0, train_df.index[-1], 5000)\n",
    "\n",
    "        plt.xticks(x_data)  # 设置 x 轴的刻度位置\n",
    "        plt.xticks(range(0, train_df.index[-1], 10 * sample_step), range(0, train_df.index[-1], 10 * sample_step))\n",
    "        plt.xlabel(\"step\")  # 设置 x 轴的标签为“step”\n",
    "\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "plot_learning_curves(record)"
   ],
   "id": "8da6bb5bc9dca256",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhYAAAGwCAYAAAD16iy9AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAa7VJREFUeJztnQd4VFX6xr9JTyCEEjqh994RUBalCNh1bbCKZa24umtdd1cF+6rr2l3Xhg3rCvpXQHrvvfcOgVBTSZvc//OemTu5mUzKwNST9/c8l5kkw8w9c8t5z1dthmEYQgghhBDiAyJ88SaEEEIIIYDCghBCCCE+g8KCEEIIIT6DwoIQQgghPoPCghBCCCE+g8KCEEIIIT6DwoIQQgghPiNKAkxRUZEcOXJEEhMTxWazBfrjCSGEEHIOoOxVZmamNGrUSCIiIkJHWEBUpKSkBPpjCSGEEOIDDh48KE2aNAkdYQFLhbljNWrU8Nn7FhQUyIwZM2T48OESHR0tuqHz+HQem+7j49jCF53Hp/PYgjm+jIwMZRgw5/GQERam+wOiwtfCIiEhQb2nrieSruPTeWy6j49jC190Hp/OYwuF8VUUxsDgTUIIIYT4DK+Exfjx45VSsW7t27f33d4QQgghJKzx2hXSqVMnmTVrVvEbRAXcm0IIIYSQEMVrVQAh0aBBA//sDSGEkLAEpQTy8/MlVGIQMFfl5uaK3W4X3Sjw0/gQrxEZGRl4YbFz506VwxoXFyf9+/eXl156SZo2bVrm6/Py8tRmjSo1vxhsvsJ8L1++Zyih8/h0Hpvu4+PYwhdfjg+CApl+EBehUm8BC+ADBw5oWS/J8OP4EBBar149j+9b2XPFZmAPK8m0adMkKytL2rVrJ6mpqTJhwgQ5fPiwbNq0qcz0E8Rl4HXuTJo0SUW1EkIICW9q164ttWrVkrp162o5kVcFDMNQAvHEiRNy+vRpVQjLnZycHBk9erSkp6eXm9XplbBw58yZM9KsWTN5/fXX5c4776y0xQJ5sNh5X6ebzpw5U4YNG6ZtepGu49N5bLqPj2MLX3w1vsLCQtm7d6+yZPvynu6LCpG6Vng2/Di+kydPyvHjx6Vly5al3CKYv5OTkysUFucVeVmzZk1p27at7Nq1q8zXxMbGqs0dnMj+uFj99b6hgs7j03lsuo+PY6u644OPH5Mb7vPllXkOJKZLBvsVKvsULuOrXr26WvgD9/OisufJee0R3CK7d++Whg0bns/bEEIICXN0tAxURWw+OI5eCYtHH31U5s+fL/v27ZMlS5bINddco0wlN99883nvCCGEEELCH69cIYcOHVIiAj4YBOlceOGFsmzZMvWcEEIIIcQri8U333yjupMiGBMiAz+3atXKf3tHCCGEhDjNmzeXN954wyfvNW/ePOWOQHJEuKJP2czMo5KQlyZiz0eESbD3hhBCSAgzePBg6d69u08EwcqVK6VatWo+2S8d0EZYRH00WIblnJCCgf1EGncN9u4QQggJ85ROZLxUpm0FwwFKok8eTmSM49FeXDODEEJI4CfknPzCoGyVLct02223qUSEN99809VQc+LEieoRhSB79eql0mcXLVqkMh+vuuoqqV+/vkrF7NOnT4l+WZ5cITabTT766COV4IBCkG3atJGff/75nL/T//3vf6pPF/YJn4XaUVbee+899RmoiI39/P3vf+/62w8//CBdunSR+Ph4qVOnjgwdOlSys7PFn2hjsZAoR60MG1whhBBCgsLZArt0fPq3oHz2lmcvlYSYiqc1CIodO3ZI586d5dlnn1W/27x5s3r861//Kq+99poqEIVqoihVPmrUKHnhhRfUxP7555/LFVdcIdu3by+3ncWECRPklVdekVdffVXefvttGTNmjOzfv19VKfWG1atXyw033KCqWN94440qI/P+++9XguXee++VVatWyYMPPihffPGFDBgwQE6dOiULFy5U/xcVspFwgf2AyEFRLfztPOpiVjFhEemMq6CwIIQQUg5JSUkSExOjJmezqea2bdvUI4QGqpGaQAh069bN9fNzzz0nkydPVhaIBx54oFyryM3OUgwvvviivPXWW7JixQoZMWKEV/sK68SQIUPkqaeeUj+jKCVEEMQKhAX6hSC+4/LLL1eVOFENu0ePHi5hgcqo1157rfo9gPXC32gkLJzVPQspLAghJFjER0cqy0GwPvt86d27d6lCkLAW/Prrr66J+uzZs2pCL4+uXYtj/TDxowR2Wlqa1/uzdetW5YqxAssErC6IAYEIgmiAhQWiBZvpgoEggiiBmLj00ktl+PDhyk0CS4w/0SbGwmCMBSGEBB3EF8AdEYzNF1Uj3bM7UBgSFgpYHeBGWLdunZqoK2oRH+2WnYh980f3V1gp1qxZI19//bWq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rDzzzDPqUUd0Hp/OY9N9fBxb+KLz+HQeWziML+DBm4QQQgjRF20sFoQQQggJPhQWhBBCCPEZFBaEEEII8RkUFoQQQgjxGdoIi3fffVeaN28ucXFx0q9fP1mxYoWEEuPHj1eVRq1b+/btXX/Pzc2VcePGSZ06daR69epy3XXXybFjx0q8x4EDB+Syyy6ThIQEqVevnjz22GNSWFhY4jXz5s2Tnj17qmjh1q1by8SJE/0yngULFsgVV1yhKrBhLFOmTCnxd8QEP/3009KwYUOJj4+XoUOHys6dO0u85tSpUzJmzBhV4KVmzZpy5513SlZWVonXbNiwQS666CJ1XFFp7pVXXim1L99//736LvGaLl26yNSpU/06tttuu63UsRwxYkRYjO2ll16SPn36qMq3OIeuvvpq2b59e4nXBPJc9PV1W5nxDR48uNTxu/fee0N+fO+//7507drVVRSpf//+Mm3aNC2OW2XGF67HzRMvv/yy2v8///nP2hy/Ehga8M033xgxMTHGJ598YmzevNm46667jJo1axrHjh0zQoVnnnnG6NSpk5Gamurajh8/7vr7vffea6SkpBizZ882Vq1aZVxwwQXGgAEDXH8vLCw0OnfubAwdOtRYu3atMXXqVCM5Odl48sknXa/Zs2ePkZCQYDz88MPGli1bjLffftuIjIw0pk+f7vPx4PP//ve/Gz/++COyiozJkyeX+PvLL79sJCUlGVOmTDHWr19vXHnllUaLFi2Ms2fPul4zYsQIo1u3bsayZcuMhQsXGq1btzZuvvlm19/T09ON+vXrG2PGjDE2bdpkfP3110Z8fLzxwQcfuF6zePFiNcZXXnlFjfkf//iHER0dbWzcuNFvYxs7dqzad+uxPHXqVInXhOrYLr30UuPTTz9Vn7lu3Tpj1KhRRtOmTY2srKyAn4v+uG4rM77f/e536rOsxw/HI9TH9/PPPxu//vqrsWPHDmP79u3G3/72N3U+YKzhftwqM75wPW7urFixwmjevLnRtWtX46GHHnL9PtyPnxUthEXfvn2NcePGuX622+1Go0aNjJdeeskIJWGBicYTZ86cURfQ999/7/rd1q1b1aS2dOlS9TNOooiICOPo0aOu17z//vtGjRo1jLy8PPXz448/rsSLlRtvvFHdbP2J++RbVFRkNGjQwHj11VdLjDE2NlZNoAAnPf7fypUr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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 23
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 测试集",
   "id": "97ccb8fe2b3bd9b1"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-05T07:28:14.472463Z",
     "start_time": "2025-02-05T07:28:14.439552Z"
    }
   },
   "cell_type": "code",
   "source": [
    "model.eval()  #验证模式\n",
    "loss = evaluating(model, test_loader, loss_fct)  #测试集损失\n",
    "print(f\"loss:     {loss:.4f}\")"
   ],
   "id": "68a506d3cc6360bc",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3364\n"
     ]
    }
   ],
   "execution_count": 24
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "c5f47f0a8e2768cc"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
